using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;

namespace CKY.AgentPlatform.Middleware
{
    /// <summary>
    /// 数据验证中间件
    /// </summary>
    public class DataValidationMiddleware : IMiddleware, ITransientDependency
    {
        private readonly ILogger<DataValidationMiddleware> _logger;

        public DataValidationMiddleware(ILogger<DataValidationMiddleware> logger)
        {
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            try
            {
                // 验证请求内容类型
                if (context.Request.Method == "POST" || context.Request.Method == "PUT" || context.Request.Method == "PATCH")
                {
                    var contentType = context.Request.ContentType;
                    if (string.IsNullOrEmpty(contentType) || !contentType.Contains("application/json"))
                    {
                        context.Response.StatusCode = 400;
                        await context.Response.WriteAsJsonAsync(new
                        {
                            success = false,
                            error = "不支持的Content-Type，请使用application/json",
                            code = 400
                        });
                        return;
                    }
                }

                // 验证请求大小限制
                if (context.Request.ContentLength > 10 * 1024 * 1024) // 10MB
                {
                    context.Response.StatusCode = 413;
                    await context.Response.WriteAsJsonAsync(new
                    {
                        success = false,
                        error = "请求内容过大，最大支持10MB",
                        code = 413
                    });
                    return;
                }

                // 记录请求信息
                _logger.LogInformation("收到请求: {Method} {Path} from {IP}", 
                    context.Request.Method, 
                    context.Request.Path, 
                    context.Connection.RemoteIpAddress);

                await next(context);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "数据验证中间件发生错误");
                context.Response.StatusCode = 500;
                await context.Response.WriteAsJsonAsync(new
                {
                    success = false,
                    error = "服务器内部错误",
                    code = 500
                });
            }
        }
    }

    /// <summary>
    /// 安全中间件
    /// </summary>
    public class SecurityMiddleware : IMiddleware, ITransientDependency
    {
        private readonly ILogger<SecurityMiddleware> _logger;

        public SecurityMiddleware(ILogger<SecurityMiddleware> logger)
        {
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            try
            {
                // 添加安全响应头
                context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
                context.Response.Headers.Add("X-Frame-Options", "DENY");
                context.Response.Headers.Add("X-XSS-Protection", "1; mode=block");
                context.Response.Headers.Add("Referrer-Policy", "strict-origin-when-cross-origin");
                context.Response.Headers.Add("Permissions-Policy", "camera=(), microphone=(), geolocation=()");

                // 验证HTTPS（生产环境）
                if (!context.Request.IsHttps && Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Production")
                {
                    context.Response.StatusCode = 403;
                    await context.Response.WriteAsJsonAsync(new
                    {
                        success = false,
                        error = "只允许HTTPS请求",
                        code = 403
                    });
                    return;
                }

                // 记录安全相关信息
                var clientIp = context.Connection.RemoteIpAddress?.ToString();
                var userAgent = context.Request.Headers["User-Agent"].ToString();
                
                _logger.LogDebug("安全检查: {IP} {UserAgent}", clientIp, userAgent);

                await next(context);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "安全中间件发生错误");
                context.Response.StatusCode = 500;
                await context.Response.WriteAsJsonAsync(new
                {
                    success = false,
                    error = "服务器内部错误",
                    code = 500
                });
            }
        }
    }

    /// <summary>
    /// 请求日志中间件
    /// </summary>
    public class RequestLoggingMiddleware : IMiddleware, ITransientDependency
    {
        private readonly ILogger<RequestLoggingMiddleware> _logger;

        public RequestLoggingMiddleware(ILogger<RequestLoggingMiddleware> logger)
        {
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            var startTime = DateTime.UtcNow;
            var requestId = Guid.NewGuid().ToString("N");

            // 添加请求ID到响应头
            context.Response.Headers.Add("X-Request-ID", requestId);

            try
            {
                _logger.LogInformation("开始处理请求: {RequestId} {Method} {Path}", 
                    requestId, context.Request.Method, context.Request.Path);

                await next(context);

                var duration = DateTime.UtcNow - startTime;
                var statusCode = context.Response.StatusCode;

                _logger.LogInformation("请求处理完成: {RequestId} {StatusCode} {Duration}ms", 
                    requestId, statusCode, duration.TotalMilliseconds);

                // 记录慢请求
                if (duration.TotalMilliseconds > 5000)
                {
                    _logger.LogWarning("慢请求检测: {RequestId} {Method} {Path} 耗时 {Duration}ms", 
                        requestId, context.Request.Method, context.Request.Path, duration.TotalMilliseconds);
                }
            }
            catch (Exception ex)
            {
                var duration = DateTime.UtcNow - startTime;
                _logger.LogError(ex, "请求处理异常: {RequestId} {Method} {Path} 耗时 {Duration}ms", 
                    requestId, context.Request.Method, context.Request.Path, duration.TotalMilliseconds);
                throw;
            }
        }
    }

    /// <summary>
    /// 限流中间件
    /// </summary>
    public class RateLimitMiddleware : IMiddleware, ITransientDependency
    {
        private readonly ILogger<RateLimitMiddleware> _logger;
        private static readonly Dictionary<string, List<DateTime>> _requestHistory = new Dictionary<string, List<DateTime>>();
        private static readonly object _lock = new object();

        public RateLimitMiddleware(ILogger<RateLimitMiddleware> logger)
        {
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            var clientIp = context.Connection.RemoteIpAddress?.ToString() ?? "unknown";
            var now = DateTime.UtcNow;

            // 清理过期的请求记录（超过1分钟）
            CleanupOldRequests(now);

            // 检查限流
            if (IsRateLimited(clientIp, now))
            {
                _logger.LogWarning("触发限流: {IP}", clientIp);
                context.Response.StatusCode = 429;
                await context.Response.WriteAsJsonAsync(new
                {
                    success = false,
                    error = "请求过于频繁，请稍后再试",
                    code = 429
                });
                return;
            }

            // 记录请求
            RecordRequest(clientIp, now);

            await next(context);
        }

        private bool IsRateLimited(string clientIp, DateTime now)
        {
            lock (_lock)
            {
                if (!_requestHistory.ContainsKey(clientIp))
                    return false;

                var requests = _requestHistory[clientIp];
                var recentRequests = requests.Count(r => (now - r).TotalSeconds < 60);

                // 每分钟最多100个请求
                return recentRequests >= 100;
            }
        }

        private void RecordRequest(string clientIp, DateTime now)
        {
            lock (_lock)
            {
                if (!_requestHistory.ContainsKey(clientIp))
                {
                    _requestHistory[clientIp] = new List<DateTime>();
                }

                _requestHistory[clientIp].Add(now);
            }
        }

        private void CleanupOldRequests(DateTime now)
        {
            lock (_lock)
            {
                foreach (var kvp in _requestHistory.ToList())
                {
                    kvp.Value.RemoveAll(r => (now - r).TotalSeconds > 60);
                    
                    if (kvp.Value.Count == 0)
                    {
                        _requestHistory.Remove(kvp.Key);
                    }
                }
            }
        }
    }
}